/* Andreas Baum
 * ConnectionManager.java
 * Handles the communication between 2 users
 * CS 78 - Networks
 */


/* 
 * The notion of "server" in this project can lead to confusion: 
 * Indeed, it is employed with two separate meanings.
 * 1. The central login server
 * 2. The "server" side of the iTunes connection to which another proxy connect
 * , and which allows another user to access the user's iTunes library.
 */

package server;

import java.io.IOException;
import java.util.Hashtable;

public class ConnectionManager {

	private static Hashtable<String, ServerThread> connections;

	private static ConnectionManager cm;


	/** Constructor is private so nobody can outside can call it
	 *	This guarantees uniqueness of the Connection Manager */
	private ConnectionManager() {
		connections = new Hashtable<String, ServerThread>();
	}

	/** Returns the connection manager if there is one. 
	 *	If not, creates one (the first one is created this way) */
	public static ConnectionManager getConnectionManager() {

		if (cm==null)
			cm = new ConnectionManager();

		return cm;
	}
	
	/** Updates the user list when a user joins the server
	  *	Informs all existing users. */
	public void logInUser(String name, ServerThread thread){
		if(!connections.isEmpty()) {
			Object[] threads = connections.values().toArray();
			int i;
			for (i = 0; i< threads.length; i++) {
				try {
					((ServerThread) threads[i]).info(name + " has joined the server.");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		connections.put(name, thread);
	}

	/** Updates the user list when a user leaves the server
	  *	Informs all existing users. */
	public void logOutUser(String name) {
		if (doesNameExist(name)) {
		connections.remove(name);
		if(!connections.isEmpty()) {
			Object[] threads = connections.values().toArray();
			int i;
			for (i = 0; i< threads.length; i++) {
				try {
					((ServerThread) threads[i]).info(name + " has left the server.");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		}
	}

	/** Checks if a username is already being used */
	public boolean doesNameExist(String name) {
		return connections.containsKey(name);
	}

	/** returns null if there is no mapping for the key */
	public ServerThread getThread(String name) {
		return ((ServerThread) connections.get(name));
	}
	
	
	/** Returns the buddy list */
	public Object[] getBuddyList() {
		return connections.keySet().toArray();
	}
	
	/** Tells the client to start the server side of the proxy */
	public void startServer(String serverName, String clientName) {
		ServerThread server= getThread(serverName);
		server.startServerConnector(clientName);
	}
	
	/** Tells the client to start the client side of the proxy */
	public void startClient(String clientName, String serverName) {
		ServerThread client = getThread(clientName);
		String serverAddress = getThread(serverName).getAddress();
		client.startClientConnector(serverName, serverAddress);
	}

}
